#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <string>
#include <functional>
using std::cout;
using std::endl;

using func = std::function<void *(void *)>;
static int n = 1;

int numt = 5000;
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
void *buytick(pthread_t &tid)
{
    while (1)
    {
        usleep(5000);
        pthread_mutex_lock(&mutex1);
        if (numt > 0)
        {
            cout << tid << "成功抢到，还剩:" << numt-- << endl;
            pthread_mutex_unlock(&mutex1);
        }
        else
        {
            pthread_mutex_unlock(&mutex1);
            break;
        }
    }
    return nullptr;
}

class Mythread
{
public:
    static void *run(void *data)
    {
        Mythread *temp = (Mythread *)data;
        buytick(temp->_tid);
        return nullptr;
    }

    enum status
    {
        WAIT,
        RUNNING,
        EXIT
    };

    Mythread() : _name("pthread" + std::to_string(++n)), _n(n), _statu(WAIT)
    {
        _func = run;
    }

    bool start()
    {

        int get = pthread_create(&_tid, nullptr, run, (void *)this);
        // run((void*)_data.c_str());
        if (get == -1)
            return false;
        _statu = RUNNING;
        return true;
    }

    bool isRunning()
    {
        return _statu == RUNNING;
    }

    bool exit()
    {
        int get = pthread_cancel(_tid);
        if (get == -1)
            return false;
        _statu = EXIT;
        return true;
    }
    pthread_t tid()
    {
        return _tid;
    }

private:
    std::string _name;
    pthread_t _tid;
    func _func;
    status _statu;
    int _n;
};

namespace zgw
{
    class mymutex
    {
    public:
        mymutex(const mymutex &data) = default;
        mymutex &operator=(const mymutex &data) = default;

        mymutex()
        {
            pthread_mutex_init(&_mutex, nullptr);
        }

        void lock()
        {
            pthread_mutex_lock(&_mutex);
        }
        void unlock()
        {
            pthread_mutex_unlock(&_mutex);
        }

        ~mymutex()
        {
            pthread_mutex_destroy(&_mutex);
        }

    private:
        pthread_mutex_t _mutex;
    };

    class LockGuard
    {
    public:
        LockGuard(mymutex&mutex) : _mutex(mutex)
        {
            _mutex.lock();
        }
        ~LockGuard()
        {
            _mutex.unlock();
        }

    private:
        mymutex &_mutex;
    };

}

struct handdata
{
    handdata()
    {
        _a = n;
        _str = "钟哥超级nb";
    }

    static void *func(void *tpr)
    {
        handdata *temp = (handdata *)tpr;
        temp->change();
    }

    void change()
    {
        cout << "正在处理数据" << endl;
        sleep(1);
        _a += 666;
        cout << "已将处理好50%" << endl;
        _str += "bb";
        sleep(1);
        cout << "已经处理好数据了" << endl;
    }

    void printInfo()
    {
        cout << _a << " " << _str << endl;
    }
    int _a;
    std::string _str;
};

// 2.0版本
//  template <class T>
//  class Mythread
//  {
//  public:
//      // static void *run(void *data)
//      // {
//      //     std::string temp((char *)data);
//      //     while (1)
//      //     {
//      //         cout << temp << endl;
//      //         sleep(1);
//      //     }
//      //     return nullptr;
//      // }
//      static void *run(void *data)
//      {
//          std::string temp((char *)data);
//          while (1)
//          {
//              cout << temp << endl;
//              sleep(1);
//          }
//          return nullptr;
//      }

//     enum status
//     {
//         WAIT,
//         RUNNING,
//         EXIT
//     };

//     Mythread() : _name("pthread" + std::to_string(++n)), _n(n), _statu(WAIT)
//     {
//         _func = run;
//     }

//     bool start(T *data)
//     {
//         _data = data;
//         int get = pthread_create(&_tid, nullptr, &T::func, _data);
//         // run((void*)_data.c_str());
//         if (get == -1)
//             return false;
//         _statu = RUNNING;
//         return true;
//     }

//     bool isRunning()
//     {
//         return _statu == RUNNING;
//     }

//     bool exit()
//     {
//         int get = pthread_cancel(_tid);
//         if (get == -1)
//             return false;
//         _statu = EXIT;
//         return true;
//     }
//     pthread_t tid()
//     {
//         return _tid;
//     }

// private:
//     std::string _name;
//     pthread_t _tid;
//     func _func;
//     status _statu;
//     int _n;
//     T *_data;
// };

// 1.0版本
//  class Mythread
//  {
//  public:
//      static void *run(void *data)
//      {
//          std::string temp((char *)data);
//          while (1)
//          {
//              cout << temp << endl;
//              sleep(1);
//          }

//         return nullptr;
//     }

//     enum status
//     {
//         WAIT,
//         RUNNING,
//         EXIT
//     };

//     Mythread() : _name("pthread" + std::to_string(++n)),_n(n), _statu(WAIT)
//     {
//         _func = run;
//     }

//     bool start(const std::string&data)
//     {
//         _data=data;
//         int get=pthread_create(&_tid,nullptr,run,(void*)_data.c_str());
//         //run((void*)_data.c_str());
//         if(get==-1)return false;
//         _statu=RUNNING;
//         return true;
//     }

//     bool isRunning()
//     {
//         return _statu==RUNNING;
//     }

//     bool exit()
//     {
//         int get=pthread_cancel(_tid);
//         if(get==-1) return false;
//         _statu=EXIT;
//         return true;
//     }
//     pthread_t tid()
//     {
//         return _tid;
//     }
// private:
//     std::string _name;
//     pthread_t _tid;
//     std::string _data;
//     func _func;
//     status _statu;
//     int _n;
// };
